`timescale 1ns/100ps

module SoC
#(
    parameter   RAM1_SIZE = 1*1024,
                RAM2_SIZE = 16*1024
)
(
    input   wire            core_clk,
    input   wire            clint_clk,
    input   wire            rstn,
    input   wire            RxD,
    output  wire            TxD,
    output  wire    [07:00] P0
);


//-----------------------NOTE-------------------------------------------
// This SoC use a wishbone-like bus, signals are of the same to WB bus
//core_clk :    __/--\__/--\__/--\__
//ADR :         --[    ADR    ]-----
//DAT :         ________[ DAT ]-----
//CYC :         __/-----------\_____
//STB :         __/-----------\_____
//ACK :         ________/-----\_____
//---------------------Bus Marster signals----------------------
	wire [07:00]    byte_en;
    wire [63:0]     Master_WB_ADRo;        //Master address output
    wire [63:0]     Master_WB_DATi;         //Master data input
    wire [63:0]     Master_WB_DATo;         //Master data output
    wire		    Master_WB_WEo;         //Master ACK in
    wire		    Master_WB_CYCo;         //Master cycle signal output
    wire		    Master_WB_ACKi;          //Master write enable signal output
//--------------------Slave0 signals----------------------------
    wire [63:00]    Slave0_WB_DATo;
    wire            Slave0_WB_ACKo;
    wire            Slave0_WB_STBi;
//--------------------Slave1 signals----------------------------
    wire [63:00]    Slave1_WB_DATo;
    wire            Slave1_WB_ACKo;
    wire            Slave1_WB_STBi;
//-------------------Slave2 signals-----------------------------
    wire [63:00]    Slave2_WB_DATo;
    wire            Slave2_WB_ACKo;
    wire            Slave2_WB_STBi;
//--------------------Slave3 signals----------------------------
    wire [63:00]    Slave3_WB_DATo;
    wire            Slave3_WB_ACKo;
    wire            Slave3_WB_STBi;

//-------------------Slave4 signals-----------------------------
	wire [07:00]    P0_IN;             //P0 input
    wire [07:00]    P0_OUT;            //P0 output
    wire [07:00]    P0_DIR;            //P0 direction
    wire [63:00]    Slave4_WB_DATo;
    wire            Slave4_WB_ACKo;
    wire            Slave4_WB_STBi;
//-------------------Slave12 signals-----------------------------
    wire            clint_mei_o;
    wire            clint_msi_o;
    wire            clint_mti_o;
    wire [63:00]    Slave12_WB_DATo;
    wire            Slave12_WB_ACKo;
    wire            Slave12_WB_STBi;
//---------------------AnonymousCore-------------------------
    Core                            Core
    (
        .clk                   		(core_clk),
        .rstn                       (rstn), 
		.mei						(clint_mei_o),
        .msi						(clint_msi_o),
        .mti						(clint_mti_o),
        .byte_en                    (byte_en),				
        .WB_ADRo                    (Master_WB_ADRo),
        .WB_DATo                    (Master_WB_DATo),
        .WB_DATi                    (Master_WB_DATi),
        .WB_WEo                     (Master_WB_WEo),
        .WB_CYCo                    (Master_WB_CYCo),
        .WB_ACKi                    (Master_WB_ACKi)
    );
//-------------------------------------------------------------------Bus martix--------------------------------------------------------
busMartix #(    .SLV0ENABLE(1'b1),//RAM1
                .SLV0SEGLEN($clog2(RAM1_SIZE)),
                .SLV0BASADR(32'h8000_0000),
                .SLV1ENABLE(1'b1),//RAM2
                .SLV1SEGLEN($clog2(RAM2_SIZE)),
                .SLV1BASADR(32'h9000_0000),
                .SLV2ENABLE(1'b1),
                .SLV2SEGLEN(8),
                .SLV2BASADR(32'hF000_0000),
                .SLV3ENABLE(1'b1),
                .SLV3SEGLEN(8),
                .SLV3BASADR(32'hF000_0100),
                .SLV4ENABLE(1'b1),
                .SLV4SEGLEN(8),
                .SLV4BASADR(32'hF000_0200),
                .SLV5ENABLE(1'b1),//CLINT
                .SLV5SEGLEN(16),
                .SLV5BASADR(32'h1000_0000),
                .SLV6ENABLE(1'b0),
                .SLV7ENABLE(1'b0)
)
busmux(
    //--------------------Master signals-------------------
        .Master_WB_ADRo             (Master_WB_ADRo),
        .Master_WB_DATi             (Master_WB_DATi),
        .Master_WB_CYCo             (Master_WB_CYCo),
        .Master_WB_ACKi             (Master_WB_ACKi),
    //------------------Slave 0 signals---------------------
        .Slave0_WB_DATo             (Slave0_WB_DATo),
        .Slave0_WB_STBi             (Slave0_WB_STBi),
        .Slave0_WB_ACKo             (Slave0_WB_ACKo),
    //------------------Slave 1 signals---------------------
        .Slave1_WB_DATo             (Slave1_WB_DATo),
        .Slave1_WB_STBi             (Slave1_WB_STBi),
        .Slave1_WB_ACKo             (Slave1_WB_ACKo),
    //------------------Slave 2 signals---------------------
        .Slave2_WB_DATo             (Slave2_WB_DATo),
        .Slave2_WB_STBi             (Slave2_WB_STBi),
        .Slave2_WB_ACKo             (Slave2_WB_ACKo),
    //------------------Slave 3 signals---------------------
        .Slave3_WB_DATo             (Slave3_WB_DATo),
        .Slave3_WB_STBi             (Slave3_WB_STBi),
        .Slave3_WB_ACKo             (Slave3_WB_ACKo),
    //------------------Slave 4 signals----------------------
        .Slave4_WB_DATo             (Slave4_WB_DATo),
        .Slave4_WB_STBi             (Slave4_WB_STBi),
        .Slave4_WB_ACKo             (Slave4_WB_ACKo),
    //------------------Slave 12 signals---------------------
        .Slave5_WB_DATo             (Slave12_WB_DATo),
        .Slave5_WB_STBi             (Slave12_WB_STBi),
        .Slave5_WB_ACKo             (Slave12_WB_ACKo)
    //------------------Slave 6 signals---------------------
        .Slave6_WB_ACKo             (1'b1),
    //------------------Slave 7 signals---------------------
        .Slave7_WB_ACKo             (1'b1)
);

//---------------------------------------------------------Slaves--------------------------------------------------------
//----------------------Slave0 and Slave1 is RAM--------------------
    WB64_ram #(.RAM_SIZE(RAM1_SIZE))
    ram0
    (
        .clk                        (core_clk),
        .rstn                       (rstn),
        .byte_en                    (byte_en),
        .WB_ADRi                    (Master_WB_ADRo),
        .WB_DATo                    (Slave0_WB_DATo),
        .WB_DATi                    (Master_WB_DATo),
        .WB_WEi                     (Master_WB_WEo),
        .WB_CYCi                    (Master_WB_CYCo),
        .WB_STBi                    (Slave0_WB_STBi),
        .WB_ACKo                    (Slave0_WB_ACKo)
    );
    WB64_ram #(.RAM_SIZE(RAM2_SIZE))
    ram1
    (
        .clk                        (core_clk),
        .rstn                       (rstn),
        .byte_en                    (byte_en),
        .WB_ADRi                    (Master_WB_ADRo),
        .WB_DATo                    (Slave1_WB_DATo),
        .WB_DATi                    (Master_WB_DATo),
        .WB_WEi                     (Master_WB_WEo),
        .WB_CYCi                    (Master_WB_CYCo),
        .WB_STBi                    (Slave1_WB_STBi),
        .WB_ACKo                    (Slave1_WB_ACKo)
    );

    uart                            uart
    (
    //-----------------------------
        .clk                        (core_clk),
        .rstn                       (rstn),
    //UART signal
        .UART_TXD                   (TxD),
        .UART_RXD                   (RxD),
    //--------Wishbone signals-------
        .Slave_WB_ADRi              (Master_WB_ADRo[05:03]),
        .Slave_WB_DATi              (Master_WB_DATo),
        .Slave_WB_DATo              (Slave3_WB_DATo),
        .Slave_WB_WEi               (Master_WB_WEo),
        .Slave_WB_CYCi              (Master_WB_CYCo),
        .Slave_WB_STBi              (Slave3_WB_STBi),
        .Slave_WB_ACKo              (Slave3_WB_ACKo)
    );


//--------------GPIO unit--------------
    gpio                            gpio0
    (
//-------------GPIO port------------
        .P_in                       (P0_IN),
        .D_out                      (P0_OUT),
        .P_mode0                    (P0_DIR),
//------------Global signals--------
        .clk                        (core_clk),
        .rstn                       (rstn),
//-----------Wishbone BUS-----------
        .WB_ADRi                    (Master_WB_ADRo[12:03]),
        .WB_DATo                    (Slave4_WB_DATo[07:00]),
        .WB_DATi                    (Master_WB_DATo[07:00]),
        .WB_WEi                     (Master_WB_WEo),
        .WB_CYCi                    (Master_WB_CYCo),
        .WB_STBi                    (Slave4_WB_STBi),
        .WB_ACKo                    (Slave4_WB_ACKo)
    );
    clint                           clint
    ( 
        .core_clk                   (core_clk),
        .clint_clk                  (clint_clk),
        .rstn                       (rstn),
        .WB_WEi                     (Master_WB_WEo),
        .WB_ADRi                    (Master_WB_ADRo[04:03]),
        .WB_DATi                    (Master_WB_DATo),
        .WB_DATo                    (Slave12_WB_DATo), 
        .WB_CYCi                    (Master_WB_CYCo),
        .WB_STBi                    (Slave12_WB_STBi),
        .WB_ACKo                    (Slave12_WB_ACKo),
        .clint_mei_i                (1'b0),
        .clint_mei_o                (clint_mei_o),
        .clint_msi_o                (clint_msi_o),
        .clint_mti_o                (clint_mti_o)

    );

    assign P0[0] = P0_DIR[0] ? P0_OUT[0] : 1'bz;
    assign P0[1] = P0_DIR[1] ? P0_OUT[1] : 1'bz;
    assign P0[2] = P0_DIR[2] ? P0_OUT[2] : 1'bz;
    assign P0[3] = P0_DIR[3] ? P0_OUT[3] : 1'bz;
    assign P0[4] = P0_DIR[4] ? P0_OUT[4] : 1'bz;
    assign P0[5] = P0_DIR[5] ? P0_OUT[5] : 1'bz;
    assign P0[6] = P0_DIR[6] ? P0_OUT[6] : 1'bz;
    assign P0[7] = P0_DIR[7] ? P0_OUT[7] : 1'bz;
  
endmodule